# P8 = L motor PWM
# P16 = R motor PWM
# P13 = EN1&2
def motor(direction: str):
    if isPaused:
        pins.digital_write_pin(DigitalPin.P13, 0)
    else:
        if direction == "D":
            pins.analog_write_pin(AnalogPin.P8, speedPWM)
            pins.analog_write_pin(AnalogPin.P16, speedPWM)
            pins.digital_write_pin(DigitalPin.P13, 1)
        elif direction == "L":
            pins.analog_write_pin(AnalogPin.P8, speedPWM * (1 - turnRatio))
            pins.analog_write_pin(AnalogPin.P16, speedPWM * (1 + turnRatio))
            pins.digital_write_pin(DigitalPin.P13, 1)
        elif direction == "R":
            pins.analog_write_pin(AnalogPin.P8, speedPWM * (1 + turnRatio))
            pins.analog_write_pin(AnalogPin.P16, speedPWM * (1 - turnRatio))
            pins.digital_write_pin(DigitalPin.P13, 1)
        elif direction == "S":
            pins.analog_write_pin(AnalogPin.P8, 0)
            pins.analog_write_pin(AnalogPin.P16, 0)
            pins.digital_write_pin(DigitalPin.P13, 0)

def go_R():
    motor("R")
    basic.show_leds("""
        . . . # .
                # # # # #
                # . . # .
                # . . . .
                # . . . .
    """)

def on_on_event():
    global loopCnt, isToSendRf, ana_l, ana_m, ana_r, dig_l, dig_m, dig_r, dig_lmr
    loopCnt += 1
    if loopCnt >= 35:
        loopCnt = 0
        isToSendRf = True
    ana_l = 0
    ana_m = 0
    ana_r = 0
    for index in range(4):
        ana_l += pins.analog_read_pin(AnalogPin.P0)
        ana_m += pins.analog_read_pin(AnalogPin.P1)
        ana_r += pins.analog_read_pin(AnalogPin.P2)
    ana_l = ana_l / 4
    ana_m = ana_m / 4
    ana_r = ana_r / 4
    if ana_l >= thres:
        dig_l = 1
    else:
        dig_l = 0
    if ana_m >= thres:
        dig_m = 1
    else:
        dig_m = 0
    if ana_r >= thres:
        dig_r = 1
    else:
        dig_r = 0
    dig_lmr = "" + convert_to_text(dig_l) + convert_to_text(dig_m) + convert_to_text(dig_r)
    car_moving()
    if isToSendRf:
        sendRF()
        isToSendRf = False
    basic.pause(50)
    control.raise_event(4800, 4801)
control.on_event(4800, 4801, on_on_event)

# toggle PAUSE/RUN
def on_on_event2():
    global isPaused
    isPaused = not (isPaused)
    if isPaused:
        led.set_brightness(20)
        music.play_tone(349, music.beat(BeatFraction.EIGHTH))
        music.play_tone(392, music.beat(BeatFraction.EIGHTH))
        music.play_tone(440, music.beat(BeatFraction.EIGHTH))
    else:
        led.set_brightness(200)
        music.play_tone(659, music.beat(BeatFraction.QUARTER))
control.on_event(4900, 4907, on_on_event2)

def sendRF():
    global RFSendStr
    RFSendStr = []
    RFSendStr.unshift("CLEAR")
    RFSendStr.unshift("thres pwm ratio")
    RFSendStr.unshift("" + convert_to_text(thres) + " | " + convert_to_text(speedPWM) + " | " + convert_to_text(turnRatio))
    RFSendStr.unshift(" ")
    RFSendStr.unshift("anaL anaM anaR")
    RFSendStr.unshift("" + convert_to_text(ana_l) + " | " + convert_to_text(ana_m) + " | " + convert_to_text(ana_r))
    RFSendStr.unshift(" ")
    RFSendStr.unshift(dig_lmr)
    while len(RFSendStr) > 0:
        radio.send_string("" + RFSendStr.pop())
        basic.pause(30)

def go_L():
    motor("L")
    basic.show_leds("""
        . # . . .
                # # # # #
                . # . . #
                . . . . #
                . . . . #
    """)

# dec speedPWM
def on_on_event3():
    global speedPWM
    if speedPWM <= 100:
        speedPWM = 100
    else:
        speedPWM += -50
control.on_event(4900, 4901, on_on_event3)

# inc Thres
def on_on_event4():
    global thres
    if thres >= 700:
        thres = 700
    else:
        thres += 50
control.on_event(4900, 4906, on_on_event4)

def go_stop():
    motor("S")
    basic.show_leds("""
        . . . . .
                . . . . .
                # # # # #
                . . . . .
                . . . . .
    """)

# inc speedPWM
def on_on_event5():
    global speedPWM
    if speedPWM >= 1000:
        speedPWM = 1000
    else:
        speedPWM += 50
control.on_event(4900, 4902, on_on_event5)

# inc turnRatio
def on_on_event6():
    global turnRatio
    if turnRatio >= 0.8:
        turnRatio = 0.8
    else:
        turnRatio += 0.1
control.on_event(4900, 4904, on_on_event6)

# dec turnRatio
def on_on_event7():
    global turnRatio
    if turnRatio <= 0.2:
        turnRatio = 0.2
    else:
        turnRatio += -0.1
control.on_event(4900, 4903, on_on_event7)

# dec Thres
def on_on_event8():
    global thres
    if thres <= 300:
        thres = 300
    else:
        thres += -50
control.on_event(4900, 4905, on_on_event8)

def on_logo_pressed():
    control.raise_event(4900, 4907)
input.on_logo_event(TouchButtonEvent.PRESSED, on_logo_pressed)

def go_D():
    motor("D")
    basic.show_leds("""
        . . # . .
                . # # # .
                . . # . .
                . . # . .
                . . # . .
    """)

def car_moving():
    global stopTmo
    # don't care
    # 000, 111, 010
    # will STOP by stopTmo
    if dig_lmr == "101":
        go_D()
        stopTmo = 20
    elif dig_lmr == "011":
        go_L()
        stopTmo = 20
    elif dig_lmr == "110":
        go_R()
        stopTmo = 20
    elif dig_lmr == "100":
        go_R()
        stopTmo = 20
    elif dig_lmr == "001":
        go_L()
        stopTmo = 20

dig_lmr = ""
dig_r = 0
dig_m = 0
dig_l = 0
ana_r = 0
ana_m = 0
ana_l = 0
isToSendRf = False
loopCnt = 0
stopTmo = 0
turnRatio = 0
speedPWM = 0
thres = 0
isPaused = False
RFSendStr: List[str] = []
led.set_brightness(200)
radio.set_group(180)
radio.send_string("CLEAR")
radio.send_string("Tracking Car V4.0")
basic.show_string("TrackCar V4.0")
pins.set_pull(DigitalPin.P0, PinPullMode.PULL_NONE)
pins.set_pull(DigitalPin.P1, PinPullMode.PULL_NONE)
pins.set_pull(DigitalPin.P2, PinPullMode.PULL_NONE)
isPaused = False
thres = 450
speedPWM = 300
turnRatio = 0.4
stopTmo = 0
RFSendStr = []
pins.set_audio_pin_enabled(False)
music.set_built_in_speaker_enabled(True)
basic.pause(1000)
control.raise_event(4800, 4801)

# stop TMO
def on_every_interval():
    global stopTmo
    if stopTmo > 0:
        stopTmo += -1
        if stopTmo == 0:
            go_stop()
loops.every_interval(100, on_every_interval)
